package cn.sowz.test;

import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Before;
import org.junit.Test;

import java.util.List;

public class Demo07 {
    private ProcessEngine processEngine;
    @Before
    public void before() throws Exception {
        // 启动引擎
        this.processEngine = ProcessEngines.getDefaultProcessEngine();
    }

    // 流程部署
    @Test
    public void testDeploy(){
        // 部署流程文件-资源操作-RepositoryService
        RepositoryService repositoryService = this.processEngine.getRepositoryService();
        // 加载流程文件+流程图片,并实现部署
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("bpmn/leave-student.bpmn")
                .name("学生请假流程")
                .deploy();
        // 输出部署的一些信息
        System.out.println("流程部署ID:"+deploy.getId());
        System.out.println("流程部署名称:"+deploy.getName());
    }

    // 对应业务：张三同学请假
    // 1:填写请假单- 开始时间，结束时间，请假理由--然后添加到请假记录表：leave_record ---- 得到id：1
    // 2:启动流程，将请假单id绑定在流程实例的businessKey属性上
    // 启动实例流程---同时绑定businessKey
    @Test
    public void testStartProcess(){
        // 步骤1： 填写请假单
        Long id = 1L; // 假装已经添加成功返回id --- businessKey
        // 启动流程实例--涉及流程运行/执行--RuntimeService
        RuntimeService runtimeService = this.processEngine.getRuntimeService();

        // 参数：leaveProcess 是在定义bpmn流程图时候自定的，不同流程图，key不一样
        // 流程实例对象--映射到act_hi_procinst
        // ProcessInstance instance = runtimeService.startProcessInstanceByKey("leave-student");
        ProcessInstance instance = runtimeService.startProcessInstanceByKey("leave-student", id.toString());

        // 获取流程实例的相关信息s
        System.out.println("流程定义的ID:"+instance.getProcessDefinitionId());
        System.out.println("流程实例的ID:"+instance.getId());
        System.out.println("流程实例的BusinessKey:"+instance.getBusinessKey());
    }

    // 对应业务：某个代办任务负责人处理（审核）任务，结果：同意，不同意，根据业务要求执行后续逻辑

    // 班主任进行学生请假审核
    // 1: 获取流程实例绑定businessKey，然后通过businessKey查询请假单，再做审核通过/审核拒绝操作

    // 任务处理：任务处理之后，流程按照所画流程图的流程执行往后执行（分支操作，需要使用后面学得网关）
    @Test
    public void testCompleteTask(){
        // 启动activiti7流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 处理任务--涉及任务处理(task)--TaskService
        TaskService taskService = processEngine.getTaskService();
        RuntimeService runtimeService = processEngine.getRuntimeService();

        List<Task> taskList = taskService.createTaskQuery()
                .processDefinitionKey("leave-student") // 查询条件：流程定义的kev--区分不同审批流程
                .taskAssignee("asan") // 查询条件： 节点（任务）审核人（负责人）
                .list();

        // 处理
        for (Task task : taskList) {
            // 先获取流程实例绑定的businessKey
            // task 对象没有businessKey属性,需要通过processInstanceId属性间接查询流程实例对象获取
            String processInstanceId = task.getProcessInstanceId();
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                    .processInstanceId(processInstanceId)
                    .singleResult();
            String businessKey = processInstance.getBusinessKey(); // 假装查询请假单信息
            System.out.println(businessKey);
            taskService.complete(task.getId());
        }
    }

    // 流程定义挂起与激活
    @Test
    public void testSuspendAllProcessInstance(){
        // 获取RepositoryService
        RepositoryService repositoryService = this.processEngine.getRepositoryService();
        // 获取流程定义对象
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey("leave-student")
                .singleResult();
        boolean suspended = processDefinition.isSuspended(); // 是否挂起
        System.out.println("suspended="+suspended);
        if (suspended) {
            // 已经挂起--->激活
            repositoryService.activateProcessDefinitionById(
                    processDefinition.getId(),true,null
            );
        }else{
            // 没有挂起--->挂起来
            // 参数2：true，表示 该流程定义对应的所有流程实例挂起
            repositoryService.suspendProcessDefinitionById(
                    processDefinition.getId(),true,null);
        }
    }

    //单个实例挂起
    @Test
    public void testSuspendSingleProcessInstance(){
        // 流程实例Id
        String processInstanceId = "10001";
        // 获取RuntimeService
        RuntimeService runtimeService = this.processEngine.getRuntimeService();
        // 根据流程实例Id获取流程实例对象
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(processInstanceId)
                .singleResult();
        boolean suspended = processInstance.isSuspended();
        if (suspended) {
            // 挂起来--->激活
            runtimeService.activateProcessInstanceById(processInstanceId);
        }else{
            // 激活中--->挂起来
            runtimeService.suspendProcessInstanceById(processInstanceId);
        }
    }

    // 测试挂起的还可以不可以继续往下走
    @Test
    public void testCompleteTask2(){
        TaskService taskService = this.processEngine.getTaskService();
        Task task = taskService.createTaskQuery().processInstanceId("2501").singleResult();
        taskService.complete(task.getId());
    }
}
